home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
os2
/
bind493a.zip
/
named
/
ns_maint.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-22
|
27KB
|
1,102 lines
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_maint.c 4.39 (Berkeley) 3/2/91";
static char rcsid[] = "$Id: ns_maint.c,v 8.11 1995/12/22 10:20:30 vixie Exp $";
#endif /* not lint */
/*
* ++Copyright++ 1986, 1988
* -
* Copyright (c) 1986, 1988
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* -
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies, and that
* the name of Digital Equipment Corporation not be used in advertising or
* publicity pertaining to distribution of the document or software without
* specific, written prior permission.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
* -
* --Copyright--
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <sys/wait.h>
#include <stdio.h>
#include <syslog.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include "named.h"
#ifdef USE_UTIME
# include <utime.h>
#endif
static int xfers_running, /* # of xfers running */
xfers_deferred, /* # of needed xfers not run yet */
qserials_running,
alarm_pending, /* flag */
nxfers __P((struct zoneinfo *, int));
static void startxfer __P((struct zoneinfo *)),
abortxfer __P((struct zoneinfo *)),
addxfer __P((struct zoneinfo *)),
tryxfer __P((void));
#define qserial_qfull() (qserials_running == MAXQSERIAL)
#ifdef CLEANCACHE
static time_t cache_time;
#endif
#ifdef XSTATS
static time_t stats_time;
#endif
/*
* Invoked at regular intervals by signal interrupt; refresh all secondary
* zones from primary name server and remove old cache entries. Also,
* ifdef'd ALLOW_UPDATES, dump database if it has changed since last
* dump/bootup.
*/
void
ns_maint()
{
register struct zoneinfo *zp;
int zonenum;
gettime(&tt);
dprintf(1, (ddt, "\nns_maint(); now %s", ctimel(tt.tv_sec)));
alarm_pending = 0;
for (zp = zones, zonenum = 0; zp < &zones[nzones]; zp++, zonenum++) {
#ifdef DEBUG
if (debug >= 2)
printzoneinfo(zonenum);
#endif
if (tt.tv_sec >= zp->z_time && zp->z_refresh > 0) {
switch (zp->z_type) {
case Z_CACHE:
doachkpt();
ns_refreshtime(zp, tt.tv_sec);
break;
case Z_SECONDARY:
#ifdef STUBS
case Z_STUB:
#endif
if (zp->z_serial != 0 &&
((zp->z_lastupdate + zp->z_expire) <
tt.tv_sec)
) {
zp->z_serial = 0;
}
if (zp->z_flags &
(Z_NEED_RELOAD|Z_NEED_XFER|Z_QSERIAL)) {
ns_refreshtime(zp, tt.tv_sec);
break;
}
if (zp->z_flags & Z_XFER_RUNNING) {
abortxfer(zp);
break;
}
qserial_query(zp);
break;
#ifdef ALLOW_UPDATES
case Z_PRIMARY:
/*
* Checkpoint the zone if it has changed
* since we last checkpointed
*/
if (zp->z_flags & Z_CHANGED) {
zonedump(zp);
ns_refreshtime(zp, tt.tv_sec);
}
break;
#endif /* ALLOW_UPDATES */
}
gettime(&tt);
}
}
#ifdef CLEANCACHE
if ((cache_time + cache_interval) <= tt.tv_sec) {
if (cache_time)
remove_zone(hashtab, 0, 0);
cache_time = tt.tv_sec;
}
#endif
#ifdef XSTATS
if (stats_time + stats_interval <= tt.tv_sec) {
if (stats_time)
ns_logstats();
stats_time = tt.tv_sec;
}
#endif
if (!needmaint)
sched_maint();
dprintf(1, (ddt, "exit ns_maint()\n"));
}
/*
* Find when the next refresh needs to be and set
* interrupt time accordingly.
*/
void
sched_maint()
{
register struct zoneinfo *zp;
struct itimerval ival;
#ifdef CLEANCACHE
time_t next_refresh = cache_time + cache_interval;
#else
time_t next_refresh = 0;
#endif
static time_t next_alarm;
for (zp = zones; zp < &zones[nzones]; zp++)
if (zp->z_time != 0 &&
(next_refresh == 0 || next_refresh > zp->z_time))
next_refresh = zp->z_time;
/*
* Schedule the next call to ns_maint.
* Don't visit any sooner than maint_interval.
*/
bzero((char *)&ival, sizeof ival);
if (next_refresh != 0) {
if (next_refresh == next_alarm && alarm_pending) {
dprintf(1, (ddt, "sched_maint: no schedule change\n"));
return;
}
/*
* tv_sec can be an unsigned long, so we can't let
* it go negative.
*/
if (next_refresh < tt.tv_sec)
next_refresh = tt.tv_sec;
ival.it_value.tv_sec = next_refresh - tt.tv_sec;
if ((long) ival.it_value.tv_sec < maint_interval)
ival.it_value.tv_sec = maint_interval;
next_alarm = next_refresh;
alarm_pending = 1;
}
(void) setitimer(ITIMER_REAL, &ival, (struct itimerval *)NULL);
dprintf(1, (ddt, "sched_maint: Next interrupt in %lu sec\n",
(u_long)ival.it_value.tv_sec));
}
/*
* Mark a zone "up to date" after named-xfer tells us this or we
* discover it through the qserial_*() logic.
*/
static void
markUpToDate(zp)
struct zoneinfo *zp;
{
struct stat f_time;
zp->z_flags &= ~Z_SYSLOGGED;
zp->z_lastupdate = tt.tv_sec;
ns_refreshtime(zp, tt.tv_sec);
/*
* Restore Z_AUTH in case expired,
* but only if there were no errors
* in the zone file.
*/
if ((zp->z_flags & Z_DB_BAD) == 0)
zp->z_flags |= Z_AUTH;
if (zp->z_source) {
#if defined(USE_UTIME)
struct utimbuf t;
t.actime = tt.tv_sec;
t.modtime = tt.tv_sec;
(void) utime(zp->z_source, &t);
#else
struct timeval t[2];
t[0] = tt;
t[1] = tt;
(void) utimes(zp->z_source, t);
#endif /* USE_UTIME */
}
/* we use "stat" to set zp->z_ftime instead of just
setting it to tt.tv_sec in order to avoid any
possible rounding problems in utimes(). */
if (stat(zp->z_source, &f_time) != -1)
zp->z_ftime = f_time.st_mtime;
/* XXX log if stat fails? */
}
/*
* Query for the serial number of a zone, so that
* we can check to see if we need to transfer it.
*/
void
qserial_query(zp)
struct zoneinfo *zp;
{
struct qinfo *qp;
dprintf(1, (ddt,